{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "134e7f9d",
   "metadata": {},
   "source": [
    "# Hello, KAN!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59cf5cd0",
   "metadata": {},
   "source": [
    "### Kolmogorov-Arnold representation theorem"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f88e5321",
   "metadata": {},
   "source": [
    "Kolmogorov-Arnold representation theorem states that if $f$ is a multivariate continuous function\n",
    "on a bounded domain, then it can be written as a finite composition of continuous functions of a\n",
    "single variable and the binary operation of addition. More specifically, for a smooth $f : [0,1]^n \\to \\mathbb{R}$,\n",
    "\n",
    "\n",
    "$$f(x) = f(x_1,...,x_n)=\\sum_{q=1}^{2n+1}\\Phi_q(\\sum_{p=1}^n \\phi_{q,p}(x_p))$$\n",
    "\n",
    "where $\\phi_{q,p}:[0,1]\\to\\mathbb{R}$ and $\\Phi_q:\\mathbb{R}\\to\\mathbb{R}$. In a sense, they showed that the only true multivariate function is addition, since every other function can be written using univariate functions and sum. However, this 2-Layer width-$(2n+1)$ Kolmogorov-Arnold representation may not be smooth due to its limited expressive power. We augment its expressive power by generalizing it to arbitrary depths and widths."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebd8766a",
   "metadata": {},
   "source": [
    "### Kolmogorov-Arnold Network (KAN)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cf3b1ee",
   "metadata": {},
   "source": [
    "The Kolmogorov-Arnold representation can be written in matrix form\n",
    "\n",
    "$$f(x)={\\bf \\Phi}_{\\rm out}\\circ{\\bf \\Phi}_{\\rm in}\\circ {\\bf x}$$\n",
    "\n",
    "where \n",
    "\n",
    "$${\\bf \\Phi}_{\\rm in}= \\begin{pmatrix} \\phi_{1,1}(\\cdot) & \\cdots & \\phi_{1,n}(\\cdot) \\\\ \\vdots & & \\vdots \\\\ \\phi_{2n+1,1}(\\cdot) & \\cdots & \\phi_{2n+1,n}(\\cdot) \\end{pmatrix},\\quad {\\bf \\Phi}_{\\rm out}=\\begin{pmatrix} \\Phi_1(\\cdot) & \\cdots & \\Phi_{2n+1}(\\cdot)\\end{pmatrix}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6521452",
   "metadata": {},
   "source": [
    "We notice that both ${\\bf \\Phi}_{\\rm in}$ and ${\\bf \\Phi}_{\\rm out}$ are special cases of the following function matrix ${\\bf \\Phi}$ (with $n_{\\rm in}$ inputs, and $n_{\\rm out}$ outputs), we call a Kolmogorov-Arnold layer:\n",
    "\n",
    "$${\\bf \\Phi}= \\begin{pmatrix} \\phi_{1,1}(\\cdot) & \\cdots & \\phi_{1,n_{\\rm in}}(\\cdot) \\\\ \\vdots & & \\vdots \\\\ \\phi_{n_{\\rm out},1}(\\cdot) & \\cdots & \\phi_{n_{\\rm out},n_{\\rm in}}(\\cdot) \\end{pmatrix}$$\n",
    "\n",
    "${\\bf \\Phi}_{\\rm in}$ corresponds to $n_{\\rm in}=n, n_{\\rm out}=2n+1$, and ${\\bf \\Phi}_{\\rm out}$ corresponds to $n_{\\rm in}=2n+1, n_{\\rm out}=1$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b410498",
   "metadata": {},
   "source": [
    "After defining the layer, we can construct a Kolmogorov-Arnold network simply by stacking layers! Let's say we have $L$ layers, with the $l^{\\rm th}$ layer ${\\bf \\Phi}_l$ have shape $(n_{l+1}, n_{l})$. Then the whole network is\n",
    "\n",
    "$${\\rm KAN}({\\bf x})={\\bf \\Phi}_{L-1}\\circ\\cdots \\circ{\\bf \\Phi}_1\\circ{\\bf \\Phi}_0\\circ {\\bf x}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54bbde9a",
   "metadata": {},
   "source": [
    "In constrast, a Multi-Layer Perceptron is interleaved by linear layers ${\\bf W}_l$ and nonlinearities $\\sigma$:\n",
    "\n",
    "$${\\rm MLP}({\\bf x})={\\bf W}_{L-1}\\circ\\sigma\\circ\\cdots\\circ {\\bf W}_1\\circ\\sigma\\circ {\\bf W}_0\\circ {\\bf x}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c5f7795",
   "metadata": {},
   "source": [
    "A KAN can be easily visualized. (1) A KAN is simply stack of KAN layers. (2) Each KAN layer can be visualized as a fully-connected layer, with a 1D function placed on each edge. Let's see an example below."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "adcb5f75",
   "metadata": {},
   "source": [
    "### Get started with KANs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2571d531",
   "metadata": {},
   "source": [
    "Initialize KAN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2075ef56",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "checkpoint directory created: ./model\n",
      "saving model version 0.0\n"
     ]
    }
   ],
   "source": [
    "from kan import *\n",
    "torch.set_default_dtype(torch.float64)\n",
    "# create a KAN: 2D inputs, 1D output, and 5 hidden neurons. cubic spline (k=3), 5 grid intervals (grid=5).\n",
    "model = KAN(width=[2,5,1], grid=3, k=3, seed=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d72e076",
   "metadata": {},
   "source": [
    "Create dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "46717e8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(torch.Size([1000, 2]), torch.Size([1000, 1]))"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from kan.utils import create_dataset\n",
    "# create dataset f(x,y) = exp(sin(pi*x)+y^2)\n",
    "f = lambda x: torch.exp(torch.sin(torch.pi*x[:,[0]]) + x[:,[1]]**2)\n",
    "dataset = create_dataset(f, n_var=2)\n",
    "dataset['train_input'].shape, dataset['train_label'].shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c6add1d",
   "metadata": {},
   "source": [
    "Plot KAN at initialization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ac76f858",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 500x400 with 22 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot KAN at initialization\n",
    "model(dataset['train_input']);\n",
    "model.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddf67e30",
   "metadata": {},
   "source": [
    "Train KAN with sparsity regularization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "97111d75",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "| train_loss: 1.05e-02 | test_loss: 9.86e-03 | reg: 3.69e+00 | : 100%|█| 50/50 [00:23<00:00,  2.15it"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "# train the model\n",
    "model.fit(dataset, opt=\"LBFGS\", steps=50, lamb=0.001);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f30c3ab",
   "metadata": {},
   "source": [
    "Plot trained KAN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "92a4f67a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 500x400 with 22 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "576856cf",
   "metadata": {},
   "source": [
    "Prune KAN and replot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "7fe6fb12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.2\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 500x400 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model = model.prune()\n",
    "model.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd08ad99",
   "metadata": {},
   "source": [
    "Continue training and replot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "18a2db11",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "| train_loss: 1.78e-02 | test_loss: 1.71e-02 | reg: 5.11e+00 | : 100%|█| 50/50 [00:06<00:00,  7.45it"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.3\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model.fit(dataset, opt=\"LBFGS\", steps=50);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "8768d56c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.4\n"
     ]
    }
   ],
   "source": [
    "model = model.refine(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "46f73098",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "| train_loss: 2.91e-04 | test_loss: 3.06e-04 | reg: 5.11e+00 | : 100%|█| 50/50 [00:06<00:00,  7.25it"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.5\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model.fit(dataset, opt=\"LBFGS\", steps=50);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf35d505",
   "metadata": {},
   "source": [
    "Automatically or manually set activation functions to be symbolic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b3c0642b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fixing (0,0,0) with sin, r2=0.9999999588837324, c=2\n",
      "fixing (0,1,0) with x^2, r2=0.9999999973097223, c=2\n",
      "fixing (1,0,0) with exp, r2=0.999999987160932, c=2\n",
      "saving model version 0.6\n"
     ]
    }
   ],
   "source": [
    "mode = \"auto\" # \"manual\"\n",
    "\n",
    "if mode == \"manual\":\n",
    "    # manual mode\n",
    "    model.fix_symbolic(0,0,0,'sin');\n",
    "    model.fix_symbolic(0,1,0,'x^2');\n",
    "    model.fix_symbolic(1,0,0,'exp');\n",
    "elif mode == \"auto\":\n",
    "    # automatic mode\n",
    "    lib = ['x','x^2','x^3','x^4','exp','log','sqrt','tanh','sin','abs']\n",
    "    model.auto_symbolic(lib=lib)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "821ba616",
   "metadata": {},
   "source": [
    "Continue training till machine precision"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c0800415",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "| train_loss: 1.97e-15 | test_loss: 1.87e-15 | reg: 5.11e+00 | : 100%|█| 50/50 [00:03<00:00, 15.86it"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "saving model version 0.7\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model.fit(dataset, opt=\"LBFGS\", steps=50);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e39da499",
   "metadata": {},
   "source": [
    "Obtain the symbolic formula"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bf44f7e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 1.0 e^{1.0 x_{2}^{2} + 1.0 \\sin{\\left(3.1416 x_{1} \\right)}}$"
      ],
      "text/plain": [
       "1.0*exp(1.0*x_2**2 + 1.0*sin(3.1416*x_1))"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from kan.utils import ex_round\n",
    "\n",
    "ex_round(model.symbolic_formula()[0][0],4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16e635f0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
